/********************************************************************
 * Filename:	TestInterface.c
 * Description: The testing interface.
 * Group 2:		nachOS
 * Author(s):	Daniel Fairweather
 * Class:		CSE 325
 * Instructor:	David Duggan
 * Assignment:	Lab #8 File System Implementation
 * Assigned:	4/16/2013
 * Due:			4/30/2013
 ********************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "TestCommands.h"

int redirection = 0;        /* Whether or not redirection mode is enabled. */
char command[100] = {0};    /* The command entered by the user. */
char args[10][100] = {0};   /* The arguments of the command. */
char argc = 0;              /* The number of arguments entered. */
char buffer[1000] = {0};    /* A buffer for user input. */

/* Prototypes */
void parseCommand();
void runCommand();

int main(){
     while(1){
        //if(redirection == 0){
            printf("\033[1m");
        //}
        printf(">>> ");

        /* Get a string from the user. */
        fgets(buffer, 100, stdin);

        /* Print out the command if redirection is on. */
        if(redirection == 1){
            printf("%s", buffer);
        }
        //else{
            printf("\033[m");
        //}

        /* If the string is a command, parse it and run it. */
        if(buffer[0] != '\n' && buffer[0] != '*'){
            parseCommand();
            runCommand();
        }
        
    }
}



void parseCommand(){
    int i, j = 0;
    argc = 0;

    /* Normailize the data. */
    for(i = 0; i < strlen(buffer); i++){
        buffer[i] = tolower(buffer[i]);
    }
    buffer[strlen(buffer)-1] = '\0';

    /* Parse the command. */
    for(i = 0; i < strlen(buffer); i++){
        if(buffer[i] == ' '){
            break;
        }
        command[i] = buffer[i];
    }
    command[i] = '\0';

    /* If there are no arguments, just return. */
    if(buffer[i] == '\0'){
        return;
    }

    /* Parse the arguments. */
    for(i++; ; i++){
        if(buffer[i] == ' ' || buffer[i] == '\0'){
            args[argc][j] = '\0';
            j = 0;
            argc++;
            if(buffer[i] == '\0'){
                return;
            }
        }
        else{
            args[argc][j] = buffer[i];
            j++;
        }
    }
}


void runCommand(){
    /* init_fs */
    if(strcmp(command, "init_fs") == 0){
        if(argc == 1){
            init_fs(atoi(args[0]));
            return;
        }
        printf("Usage: init_fs [device]\n");
    }

    /* list */
    else if(strcmp(command, "list") == 0){
        if(argc == 0){
           list();
            return;
        }
        else if(argc == 1){
            if(strcmp(args[0], "devices") == 0){
                list_devices();
                return;
            }
            else if(strcmp(args[0], "directory") == 0){
                list_directory();
                return;
            }
        }
        else if(argc == 2){
            if(strcmp(args[0], "fileinfo") == 0){
                list_file(args[1]);
                return;
            }
        }
        printf("Usage: list {devices | fileinfo [filename] | directory}\n");
    }

    /* format */
    else if(strcmp(command, "format") == 0){
        if(argc == 3){
            format(atoi(args[0]),args[1],atoi(args[2]));
            return;
        }
        printf("Usage: format [device] [filesystem_name] [block_size]\n");
    }

    /* mount */
    else if(strcmp(command, "mount") == 0){
        if(argc == 1){
            mount(args[0]);
            return;
        }
        printf("Usage: mount [filesystem_name]\n");
    }

    /* unmount */
    else if(strcmp(command, "unmount") == 0){
        if(argc == 1){
            unmount(args[0]);
            return;
        }
        printf("Usage: unmount [filesystem_name]\n");
    }

    /* open */
    else if(strcmp(command, "open") == 0){
        if(argc == 2){
            int mode;
            if(strcmp(args[1], "new") == 0){
                open(args[0],0);
                return;
            }
            else if(strcmp(args[1], "read-only") == 0){
                open(args[0],1);
                return;
            }
            else if(strcmp(args[1], "read-write") == 0){
                open(args[0],2);
                return;
            }
        }
        printf("Usage: open [filename] [new | read-only | read-write]\n");
    }

    /* read */
    else if(strcmp(command, "read") == 0){
        if(argc == 3){
            read(atoi(args[0]), atoi(args[1]), atoi(args[2]));
            return;
        }
        printf("Usage: read [filehandle] [block_number] [buffer_pointer]\n");
    }

    /* write */
    else if(strcmp(command, "write") == 0){
        if(argc == 3){
            write(atoi(args[0]), atoi(args[1]), atoi(args[2]));
            return;
        }
        printf("Usage: write [filehandle] [block_number] [buffer_pointer]\n");
    }

    /* close */
    else if(strcmp(command, "close") == 0){
        if(argc == 1){
            close(atoi(args[0]));
            return;
        }
        printf("Usage: close [filehandle]\n");
    }

    /* delete */
    else if(strcmp(command, "delete") == 0){
        if(argc == 1){
            delete_File(args[0]);
            return;
        }
        printf("Usage: read [filename]\n");
    }

    /* ls */
    else if(strcmp(command, "ls") == 0){
        if(argc == 0){
            ls();
            return;
        }
        printf("Usage: ls\n");
    }

    /* mkdir */
    else if(strcmp(command, "mkdir") == 0){
        if(argc == 1){
            mkdir(args[0]);
            return;
        }
        printf("Usage: mkdir [directory_name]\n");
    }

    /* cd */
    else if(strcmp(command, "cd") == 0){
        if(argc == 1){
            cd(args[0]);
            return;
        }
        printf("Usage: cd [directory_name]\n");
    }

    /* clear */
    else if(strcmp(command, "clear") == 0){
        #ifdef _WIN32
            system("cls");
        #else
            system("clear");
        #endif 
    }

    /* redirection */
    else if(strcmp(command, "redirection") == 0){
        if(argc == 1){
            if(strcmp(args[0], "on") == 0){
                printf("\033[m");
                redirection = 1;
                return;
            }
            else if(strcmp(args[0], "off") == 0){
                redirection = 0;
                return;
            }
        }
        printf("Usage: redirection [on | off]\n");
    }

    /* quit, exit, q */
    else if(strcmp(command, "quit") == 0 || strcmp(command, "exit") == 0 || strcmp(command, "q") == 0){
        printf("\x1b[0m");
        exit(0);
    }

    /* Unknown command */
    else{
        printf("'%s' is not a recoginized command.\n", command);
    }
}